const arrange = require("./template.js")

function testArrange() {
  console.log(
    "1. 空数组排列:",
    (() => {
      const result = arrange([])
      return JSON.stringify(result) === JSON.stringify([[]])
    })()
  )

  console.log(
    "2. 单元素排列:",
    (() => {
      const result = arrange([1])
      return JSON.stringify(result) === JSON.stringify([[1]])
    })()
  )

  console.log(
    "3. 两元素排列:",
    (() => {
      const result = arrange([1, 2])
      const expected = [
        [1, 2],
        [2, 1]
      ]
      return (
        result.length === 2 &&
        JSON.stringify(result.sort()) === JSON.stringify(expected.sort())
      )
    })()
  )

  console.log(
    "4. 三元素排列:",
    (() => {
      const result = arrange([1, 2, 3])
      const expected = [
        [1, 2, 3],
        [1, 3, 2],
        [2, 1, 3],
        [2, 3, 1],
        [3, 1, 2],
        [3, 2, 1]
      ]
      return (
        result.length === 6 &&
        result.every((perm) =>
          expected.some((exp) => JSON.stringify(perm) === JSON.stringify(exp))
        )
      )
    })()
  )

  console.log(
    "5. 字符串元素排列:",
    (() => {
      const result = arrange(["a", "b"])
      const expected = [
        ["a", "b"],
        ["b", "a"]
      ]
      return (
        result.length === 2 &&
        JSON.stringify(result.sort()) === JSON.stringify(expected.sort())
      )
    })()
  )

  console.log(
    "6. 重复元素排列:",
    (() => {
      const result = arrange([1, 1, 2])
      // 重复元素的排列应该包含所有可能的排列
      return (
        result.length === 6 && // 3! = 6
        result.every((perm) => perm.length === 3)
      )
    })()
  )

  console.log(
    "7. 混合类型排列:",
    (() => {
      const result = arrange([1, "a"])
      const expected = [
        [1, "a"],
        ["a", 1]
      ]
      return (
        result.length === 2 &&
        JSON.stringify(result.sort()) === JSON.stringify(expected.sort())
      )
    })()
  )

  console.log(
    "8. 四元素排列数量:",
    (() => {
      const result = arrange([1, 2, 3, 4])
      return result.length === 24 // 4! = 24
    })()
  )

  console.log(
    "9. 每个排列长度一致:",
    (() => {
      const input = [1, 2, 3]
      const result = arrange(input)
      return result.every((perm) => perm.length === input.length)
    })()
  )

  console.log(
    "10. 排列唯一性:",
    (() => {
      const result = arrange([1, 2, 3])
      const stringified = result.map((perm) => JSON.stringify(perm))
      const unique = [...new Set(stringified)]
      return unique.length === result.length
    })()
  )

  console.log(
    "11. 包含所有元素:",
    (() => {
      const input = [1, 2, 3]
      const result = arrange(input)
      return result.every((perm) =>
        input.every((element) => perm.includes(element))
      )
    })()
  )

  console.log(
    "12. 返回新数组:",
    (() => {
      const input = [1, 2]
      const result = arrange(input)
      return result !== input && result.every((perm) => perm !== input)
    })()
  )

  console.log(
    "13. 原数组不变:",
    (() => {
      const input = [1, 2, 3]
      const originalStr = JSON.stringify(input)
      arrange(input)
      return JSON.stringify(input) === originalStr
    })()
  )

  console.log(
    "14. 对象元素排列:",
    (() => {
      const obj1 = { id: 1 }
      const obj2 = { id: 2 }
      const result = arrange([obj1, obj2])
      return (
        result.length === 2 &&
        result.some((perm) => perm[0] === obj1 && perm[1] === obj2) &&
        result.some((perm) => perm[0] === obj2 && perm[1] === obj1)
      )
    })()
  )

  console.log(
    "15. 布尔值排列:",
    (() => {
      const result = arrange([true, false])
      const expected = [
        [true, false],
        [false, true]
      ]
      return (
        result.length === 2 &&
        JSON.stringify(result.sort()) === JSON.stringify(expected.sort())
      )
    })()
  )

  console.log(
    "16. null和undefined排列:",
    (() => {
      const result = arrange([null, undefined])
      return (
        result.length === 2 &&
        result.some((perm) => perm[0] === null && perm[1] === undefined) &&
        result.some((perm) => perm[0] === undefined && perm[1] === null)
      )
    })()
  )

  console.log(
    "17. 五元素排列数量验证:",
    (() => {
      const result = arrange([1, 2, 3, 4, 5])
      return result.length === 120 // 5! = 120
    })()
  )

  console.log(
    "18. 数学验证:",
    (() => {
      // 验证 n! 公式
      const factorial = (n) => (n <= 1 ? 1 : n * factorial(n - 1))
      const input = [1, 2, 3, 4]
      const result = arrange(input)
      return result.length === factorial(input.length)
    })()
  )

  console.log(
    "19. this上下文测试:",
    (() => {
      const obj = {
        data: [1, 2, 3],
        getArrangements: function() {
          return arrange(this.data)
        }
      }
      const result = obj.getArrangements()
      return result.length === 6 && result.every(perm => perm.length === 3)
    })()
  )

  console.log(
    "20. 方法调用this绑定:",
    (() => {
      const obj = {
        multiplier: 2,
        process: function(arr) {
          const arrangements = arrange(arr)
          return arrangements.map(perm => perm.map(item => item * this.multiplier))
        }
      }
      const result = obj.process([1, 2])
      return JSON.stringify(result) === JSON.stringify([[2, 4], [4, 2]])
    })()
  )

  console.log(
    "21. 复杂对象this绑定:",
    (() => {
      const obj = {
        items: [{ id: 1 }, { id: 2 }],
        getArrangements: function() {
          return arrange(this.items)
        }
      }
      const result = obj.getArrangements()
      return result.length === 2 && result[0][0].id === 1 && result[1][0].id === 2
    })()
  )
}

testArrange()
